home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C++ / Applications / PICSee Dust 1.01 / Primary Source / main.cpp < prev    next >
C/C++ Source or Header  |  1995-11-23  |  14KB  |  579 lines

  1. #include "main.h"
  2. #include "InitToolBox.h"
  3. #include "GraphicsBuffers.h"
  4. #include "HandleAppleEvents.h"
  5. #include "PICS_Operations.h"
  6. #include "PICS_Merge.h"
  7. #include "PICS_Split.h"
  8. #include "PICSDialogs.h"
  9. #include "PICSViewer.h"
  10. #include "PICSPreferencesDialog.h"
  11. #include "PICSCompositeDialog.h"
  12. #include "AboutDialog.h"
  13. #include "MovableModalDialogs.h"
  14. #include "KeyUtils.h"                // For CmdKeyDown()
  15. #include "SoundUtils.h"
  16. #include "SmartDragWindow.h"
  17.  
  18. // ---------------------------------------------------------------------------
  19.  
  20. enum {
  21.     kAppleMenuID = 128,
  22.     kFileMenuID,
  23.     kEditMenuID,
  24.     
  25.     kAppleMenu_About = 1,
  26.     
  27.     kFileMenu_Open = 1,
  28.     kFileMenu_Close,
  29.     kFileMenu_Save,
  30.     kFileMenu_line1,
  31.     kFileMenu_Composite,
  32.     kFileMenu_Split,
  33.     kFileMenu_Merge,
  34.     kFileMenu_line2,
  35.     kFileMenu_Prefs,
  36.     kFileMenu_line3,
  37.     kFileMenu_Quit,
  38.     
  39.     kEditMenu_Undo = 1,
  40.     kEditMenu_line1,
  41.     kEditMenu_Cut,
  42.     kEditMenu_Copy,
  43.     kEditMenu_Paste,
  44.     kEditMenu_Clear,
  45.     kEditMenu_line2,
  46.     kEditMenu_SelectAll,
  47.     kEditMenu_SelectNone
  48. };
  49.  
  50. // ---------------------------------------------------------------------------
  51.  
  52. static void QuitHandler();
  53. static Boolean HandleEvent(EventRecord *theEvent);
  54. static void HandleMenu(long menuCode);
  55. static void HandleUpdate(EventRecord *theEvent) ;
  56. static void HandleActivate(WindowPtr theWindow, Boolean activate, EventRecord *theEvent);
  57. static void HandleOSEvent(EventRecord *theEvt);
  58. static void AdjustMenus();
  59. static void MyBeep();
  60. static void MySnapProc(WindowPtr windowToDrag, short snapToDistance, Rect *snapRect);
  61.  
  62. // ---------------------------------------------------------------------------
  63.  
  64. static short gDone = false;
  65. short gInBackground = false;
  66.  
  67. void main() {
  68.     InitToolbox();
  69.     MaxApplZone();
  70.  
  71.     (void)InitGraphicsBuffers();
  72.     SetGraphicsBufferTransferMode(srcCopy+ditherCopy);    // For optimum quality!
  73.     InitAppleEvents(FileDispatcher, NULL, QuitHandler);
  74.     InitMovableModalDialogs(AdjustMenus);
  75.     InitSoundUtils();
  76.     InitPrefs();
  77.     
  78.     PrefsHandle prefs = LoadPrefs();
  79.     RGBColor marqueeColor;
  80.     GetPrefsMarqueeColor(prefs, &marqueeColor);
  81.     InitPICSViewer((**prefs).changeCreator, (**prefs).animationMethod, &marqueeColor);
  82.     SetPICSViewerOpenProgress((**prefs).showOpenProgress);
  83.     ReleaseResource((Handle)prefs);
  84.  
  85.     MenuHandle menu;
  86.     menu = GetMenu(128);
  87.     AddResMenu(menu, 'DRVR');
  88.     InsertMenu(menu, 0);
  89.     
  90.     menu = GetMenu(129);
  91.     InsertMenu(menu, 0);
  92.     menu = GetMenu(130);
  93.     InsertMenu(menu, 0);
  94.     DrawMenuBar();
  95.     AdjustMenus();
  96.  
  97.     EventRecord theEvent;
  98.     Boolean eventExists;
  99.  
  100.     while (!gDone) {
  101.         eventExists = WaitNextEvent(everyEvent, &theEvent, 25, NULL);
  102.  
  103.         if (eventExists) {
  104.             HandleEvent(&theEvent);
  105.         }
  106.         else {
  107.             WindowPtr theWindow = FrontWindow();
  108.             if (theWindow != NULL) {
  109.                 if (GetWindowKind(theWindow) == dialogKind) {
  110.                     // Make text edit items blink...
  111.                     short itemHit;
  112.                     (void)DialogSelect(&theEvent, &theWindow, &itemHit);
  113.                     HandleIdleModeless(theWindow);
  114.                 }
  115.  
  116.                 // Send idle event only to topmost PICSViewer
  117.                 theWindow = GetCurrentPICSViewer();
  118.                 if (theWindow != NULL)
  119.                     IdlePICSViewer(theWindow);
  120.             }
  121.         }
  122.     }
  123.     
  124.     CleanupPICSViewer();
  125. } // END main
  126.  
  127. // ---------------------------------------------------------------------------
  128.  
  129. Boolean HandleEvent(EventRecord *theEvent) {
  130.     WindowPtr theWindow;
  131.     WindowPtr topWindow = FrontWindow();
  132.     Boolean handledIt = true;
  133.     short itemHit;
  134.  
  135.     // The calls to DialogSelect here serve to update and blink
  136.     // the cursor (if the dialog contains edit text items)
  137.     if (IsDialogEvent(theEvent)) {
  138.         if (topWindow != NULL && IsMovableModal(topWindow)) {
  139.             // We call the keydown handler here (not later in
  140.             // the switch statement below) so that it's invoked
  141.             // BEFORE a call to DialogSelect. We also exit
  142.             // if the key is handled by the dialog (otherwise
  143.             // the same key is acted on by the key case in
  144.             // the switch statement below - two result for
  145.             // one action -> not good!).
  146.             if (!HandleKeyDownModeless(topWindow, theEvent))
  147.                 DialogSelect(theEvent, &theWindow, &itemHit);
  148.             else
  149.                 return(handledIt);
  150.         }
  151.         else
  152.             (void)DialogSelect(theEvent, &theWindow, &itemHit);
  153.     }
  154.  
  155.     switch(theEvent->what) {
  156.         case mouseDown:
  157.             short part;
  158.  
  159.             part = FindWindow(theEvent->where, &theWindow);
  160.  
  161.             switch(part) {
  162.                 case inMenuBar:
  163.                     AdjustMenus();
  164.                     HandleMenu(MenuSelect(theEvent->where));
  165.                 break;
  166.  
  167.                 case inSysWindow:
  168.                     SystemClick(theEvent, theWindow);
  169.                 break;
  170.  
  171.                 case inGoAway:
  172.                     if (TrackGoAway(theWindow, theEvent->where)) {
  173.                         if (IsPICSViewer(theWindow)) {
  174.                             (void)ClosePICSViewer(theWindow);
  175.                             AdjustMenus();
  176.                         }
  177.                     }
  178.                 break;
  179.  
  180.                 case inDrag:
  181.                     if ((theWindow != topWindow) && IsMovableModal(topWindow) &&
  182.                         (!CmdKeyDown()))
  183.                         MyBeep();
  184.                     else
  185.                         SuperSmartDragWindow(theWindow, theEvent->where, NULL, 15, MySnapProc);
  186.                 break;
  187.  
  188.                 case inContent:
  189.                     if (theWindow != topWindow) {
  190.                         if (IsMovableModal(topWindow))
  191.                             MyBeep();
  192.                         else
  193.                             SelectWindow(theWindow);
  194.                     }
  195.                     else {
  196.                         HandleContentClickModeless(theEvent, topWindow, itemHit);
  197.                         if (itemHit != 0 && IsPICSViewer(topWindow)) {
  198.                             SetPort(theWindow);
  199.                             ClickPICSViewer(theWindow, itemHit);
  200.                         }
  201.                     }
  202.                 break;
  203.                 
  204.                 case inGrow:
  205.                 default:
  206.                     handledIt = false;
  207.                 break;
  208.             } // END switch
  209.         break;
  210.         
  211.         case keyDown:
  212.         case autoKey:
  213.             char theKey = theEvent->message & charCodeMask;
  214.  
  215.             if (IsMovableModal(topWindow)) {
  216.             }
  217.             else {
  218.                 if (theEvent->modifiers & cmdKey) {
  219.                     long menuResult;
  220.     
  221.                     AdjustMenus();
  222.                     menuResult = MenuKey(theKey);
  223.                     if (menuResult != 0) {
  224.                         HandleMenu(menuResult);
  225.                     }
  226.                     else {
  227.                         if (IsPICSViewer(topWindow))
  228.                             KeyDownPICSViewer(topWindow, theKey);
  229.                     }
  230.                 }
  231.                 else {
  232.                     if (IsPICSViewer(topWindow))
  233.                         KeyDownPICSViewer(topWindow, theKey);
  234.                 }
  235.             }
  236.         break;
  237.         
  238.         case activateEvt:
  239.             Boolean activate;
  240.  
  241.             theWindow = WindowPtr(theEvent->message);
  242.             activate = (theEvent->modifiers & activeFlag) != 0;
  243.             if (IsMovableModal(theWindow))
  244.                 HandleActivateModeless(theWindow, activate);
  245.             else
  246.                 HandleActivate(theWindow, activate, theEvent);
  247.             AdjustMenus();
  248.         break;
  249.         
  250.         case updateEvt:
  251.             HandleUpdate(theEvent);
  252.         break;
  253.         
  254.         case osEvt:
  255.             HandleOSEvent(theEvent);
  256.         break;
  257.         
  258.         case kHighLevelEvent:
  259.             OSErr err;
  260.             err = AEProcessAppleEvent(theEvent);
  261.         break;
  262.         
  263.         default:
  264.             handledIt = true;
  265.         break;
  266.     } // END switch
  267.     
  268.     return(handledIt);
  269. } // END HandleEvent
  270.  
  271. // ---------------------------------------------------------------------------
  272.  
  273. void HandleMenu(long menuCode) {
  274.     short menuID, menuItem;
  275.     
  276.     menuID = HiWord(menuCode);
  277.     menuItem = LoWord(menuCode);
  278.  
  279.     if (menuID != 0)
  280.         HiliteMenu(0);
  281.     else
  282.         return;
  283.  
  284.     SetCursor(&qd.arrow);
  285.     DialogPtr viewer = GetCurrentPICSViewer();
  286.  
  287.     switch(menuID) {
  288.         case kAppleMenuID:
  289.             switch(menuItem) {
  290.                 case kAppleMenu_About:
  291.                     DoAbout();
  292.                 break;
  293.  
  294.                 default:
  295.                     Str255 deskName;
  296.                     GrafPtr savePort;
  297.                     GetPort(&savePort);
  298.                     GetItem(GetMHandle(128), menuItem, deskName);
  299.                     (void)OpenDeskAcc(deskName);
  300.                     SetPort(savePort);
  301.                 break;
  302.             } // END switch
  303.         break;
  304.         
  305.         case kFileMenuID:
  306.             switch(menuItem) {
  307.                 case kFileMenu_Open:
  308.                     NewPICSViewer(NULL);
  309.                     if (viewer != NULL) {
  310.                         EnableItem(GetMHandle(129), 2);
  311.                     }
  312.                 break;
  313.                 
  314.                 case kFileMenu_Close:
  315.                     if (viewer != NULL) {
  316.                         (void)ClosePICSViewer(viewer);
  317.                         AdjustMenus();
  318.                     }
  319.                 break;
  320.                 
  321.                 case kFileMenu_Save:
  322.                     if (viewer != NULL) {
  323.                         (void)SavePICSViewer(viewer);
  324.                         AdjustMenus();
  325.                     }
  326.                 break;
  327.                 
  328.                 case kFileMenu_Composite:
  329.                     if (viewer == NULL)
  330.                         SetupPICSFileComposite(NULL, NULL);
  331.                     else
  332.                         CompositePICSViewer(viewer);
  333.                 break;
  334.                 
  335.                 case kFileMenu_Split:
  336.                     if (viewer == NULL)
  337.                         SetupPICSFileSplit(NULL);
  338.                     else
  339.                         SplitPICSViewer(viewer);
  340.                 break;
  341.                 
  342.                 case kFileMenu_Merge:
  343.                     SetupMergePICTFiles(0, NULL);
  344.                 break;
  345.                 
  346.                 case kFileMenu_Prefs:
  347.                     SetupPrefsDialog();
  348.                 break;
  349.  
  350.                 case kFileMenu_Quit:
  351.                     QuitHandler();
  352.                 break;
  353.             } // END switch
  354.         break;
  355.         
  356.         case kEditMenuID:
  357.             switch(menuItem) {
  358.                 case kEditMenu_Copy:
  359.                     if (viewer != NULL) {
  360.                         CopyPICSViewerFrame(viewer);
  361.                     }
  362.                 break;
  363.                 
  364.                 case kEditMenu_SelectAll:
  365.                     if (viewer != NULL) {
  366.                         SelectEntirePICSViewerFrame(viewer, true);
  367.                     }
  368.                 break;
  369.                 
  370.                 case kEditMenu_SelectNone:
  371.                     if (viewer != NULL) {
  372.                         SelectEntirePICSViewerFrame(viewer, false);
  373.                     }
  374.                 break;
  375.             }
  376.         break;
  377.     } // END switch
  378. } // END HandleMenu
  379.  
  380. // ---------------------------------------------------------------------------
  381.  
  382. void HandleUpdate(EventRecord *theEvent) {
  383.     WindowPtr theWindow = (WindowPtr)theEvent->message;
  384.  
  385.     switch(GetWindowKind(theWindow)) {
  386.         case userKind:
  387.             BeginUpdate(theWindow);
  388.             GrafPtr savePort;
  389.         
  390.             GetPort(&savePort);
  391.             EraseRect(&theWindow->portRect);
  392.             SetPort(savePort);
  393.             EndUpdate(theWindow);
  394.         break;
  395.         
  396.         case dialogKind:
  397.             if (IsMovableModal(theWindow)) {
  398.                 HandleUpdateDialog(theWindow, theEvent, AppInBackground());
  399.             }
  400.             else if (IsPICSViewer(theWindow)) {
  401.                 UpdatePICSViewer(theWindow);
  402.             }
  403.         break;
  404.     }
  405. } // END HandleUpdate
  406.  
  407. // ---------------------------------------------------------------------------
  408.  
  409. /*
  410.     This is a quick 'n dirty method. Call this after a dialog has been
  411.     removed and before another operation takes place. Usually, if you
  412.     have a lengthy operation or another dialog shows after the previous dialog
  413.     has been dismissed, you'll get ugly white un-updated areas in your
  414.     windows where the old dialog used to be - they won't get update events
  415.     untill all of your operations are done.
  416.  
  417.     This method partially fixes things. Only our windows get updated;
  418.     windows in other processes won't, since we're not sending out real
  419.     update events to all windows...
  420. */
  421. void AppEmergencyUpdate() {
  422.     EventRecord theEvent;
  423.     WindowPtr targetWindow;
  424.     short oldRefNum;
  425.     
  426.     // We need to save the current resource file path, since
  427.     // updating the windows might change it (a window might
  428.     // need to get a resource in the app, for example, and
  429.     // we're currently pointing to another resource fork)
  430.     oldRefNum = CurResFile();
  431.  
  432.     // Update all of our windows    
  433.     targetWindow = FrontWindow();
  434.     while (targetWindow != NULL) {
  435.         // Roll up own update event (kind of)
  436.         theEvent.message = (long)targetWindow;
  437.         theEvent.what = updateEvt;
  438.         theEvent.modifiers = 0;
  439.         theEvent.when = TickCount();
  440.         theEvent.where.h = theEvent.where.v = 0;
  441.         HandleEvent(&theEvent);
  442.         
  443.         targetWindow = GetNextWindow(targetWindow);
  444.     }
  445.     
  446.     UseResFile(oldRefNum);
  447. } // END AppEmergencyUpdate
  448.  
  449. // ---------------------------------------------------------------------------
  450.  
  451. void HandleActivate(WindowPtr theWindow, Boolean activate, EventRecord *theEvent) {
  452.     GrafPtr savePort;
  453.     
  454.     GetPort(&savePort);
  455.     SetPort(theWindow);
  456.     if (IsPICSViewer(theWindow))
  457.         ActivatePICSViewer(theWindow, activate);
  458.     SetPort(savePort);
  459. } // END HandleActivate
  460.  
  461. // ---------------------------------------------------------------------------
  462.  
  463. void HandleOSEvent(EventRecord *theEvt) {
  464.     WindowPtr theWindow = FrontWindow();
  465.  
  466.     if (((theEvt->message >> 24) & 0x0FF) == suspendResumeMessage) {
  467.         if (theEvt->message & resumeFlag != 0) {
  468.             // Resume event
  469.             gInBackground = false;
  470.             SetCursor(&qd.arrow);
  471.             if ((theWindow != NULL) && IsMovableModal(theWindow)) {
  472.                 HandleActivateModeless(theWindow, true);
  473.             }
  474.             else {
  475.                 if (IsPICSViewer(theWindow))
  476.                     ActivatePICSViewer(theWindow, true);
  477.             }
  478.         }
  479.         else {
  480.             // Suspend event
  481.             gInBackground = true;
  482.             if ((theWindow != NULL) && IsMovableModal(theWindow)) {
  483.                 HandleActivateModeless(theWindow, false);
  484.             }
  485.             else {
  486.                 if (IsPICSViewer(theWindow))
  487.                     ActivatePICSViewer(theWindow, false);
  488.             }
  489.         }
  490.     }
  491. } // END HandleOSEvent
  492.  
  493. // ---------------------------------------------------------------------------
  494.  
  495. /*
  496.     AdjustMenus - called in whenever command-keys are pressed, or if the menu bar is
  497.     hit with the mouse, so the menus are adjusted only right before they're accessed.
  498. */
  499.  
  500. void AdjustMenus() {
  501.     WindowPtr topWindow = FrontWindow();
  502.     
  503.     // Enable everything, then selectively disable as necessary
  504.     EnableItem(GetMHandle(kFileMenuID), 0);
  505.     EnableItem(GetMHandle(kEditMenuID), 0);
  506.     EnableItem(GetMHandle(kAppleMenuID), 1);
  507.  
  508.     if (topWindow == NULL) {
  509.         DisableItem(GetMHandle(kFileMenuID), kFileMenu_Close);
  510.         DisableItem(GetMHandle(kFileMenuID), kFileMenu_Save);
  511.         
  512.         DisableItem(GetMHandle(kEditMenuID), 0);
  513.     }
  514.     else if (IsMovableModal(topWindow)) {
  515.         DisableItem(GetMHandle(kAppleMenuID), kAppleMenu_About);
  516.         DisableItem(GetMHandle(kFileMenuID), 0);
  517.         DisableItem(GetMHandle(kEditMenuID), 0);
  518.     }
  519.     else if (IsPICSViewer(topWindow)) {
  520.         EnableItem(GetMHandle(kFileMenuID), kFileMenu_Open);
  521.         EnableItem(GetMHandle(kFileMenuID), kFileMenu_Close);
  522.  
  523.         if (IsPICSViewerModified(topWindow)) {
  524.             EnableItem(GetMHandle(kFileMenuID), kFileMenu_Save);
  525.         }
  526.         else {
  527.             DisableItem(GetMHandle(kFileMenuID), kFileMenu_Save);
  528.         }
  529.         EnableItem(GetMHandle(kEditMenuID), kEditMenu_Copy);
  530.         EnableItem(GetMHandle(kEditMenuID), kEditMenu_SelectAll);
  531.         EnableItem(GetMHandle(kEditMenuID), kEditMenu_SelectNone);
  532.     }
  533.     DrawMenuBar();
  534. } // END AdjustMenus
  535.  
  536. // ---------------------------------------------------------------------------
  537.  
  538. void QuitHandler() {
  539.     DialogPtr viewer;
  540.     
  541.     viewer = NULL;
  542.     
  543.     do {
  544.         viewer = GetCurrentPICSViewer();
  545.         if (viewer != NULL) {
  546.             if (!ClosePICSViewer(viewer)) {
  547.                 return;
  548.             }
  549.         }
  550.     } while (viewer != NULL);
  551.  
  552.     gDone = true;
  553. } // END QuitHandler
  554.  
  555. // ---------------------------------------------------------------------------
  556.  
  557. Boolean AppInBackground() {
  558.     return(gInBackground);
  559. }
  560.  
  561. // ---------------------------------------------------------------------------
  562.  
  563. void MyBeep() {
  564.     Handle beepSnd = GetResource('SND!', 128);
  565.     if (beepSnd != NULL && CreateSndChannel(0) == noErr) {
  566.         PlayAsynch(beepSnd, 0);
  567.         WaitTillSndDone(0);
  568.         HUnlock((Handle)beepSnd);
  569.         ReleaseResource(beepSnd);
  570.         DisposeSndChannel(0);
  571.     }
  572. } // END MyBeep
  573.  
  574. // ---------------------------------------------------------------------------
  575.  
  576. void MySnapProc(WindowPtr windowToDrag, short snapToDistance, Rect *snapRect) {
  577.     WindowSnapProc(windowToDrag, snapToDistance, snapRect);
  578.     MonitorSnapProc(windowToDrag, snapToDistance, snapRect);
  579. } // END MySnapProc